import { ArgumentsHost, Catch, ExceptionFilter, Logger } from '@nestjs/common';
import { TypeORMError, QueryFailedError } from 'typeorm';
import { v4 as uuid } from 'uuid';
import { Request } from 'express';

@Catch(TypeORMError)
export class TypeormFilter implements ExceptionFilter {
  private readonly logger = new Logger();
  catch(exception: TypeORMError, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const request = ctx.getRequest<Request>();
    let params = {};
    if (Object.keys(request.query).length > 0) {
      params = { ...params, ...request.query };
    }
    if (Object.keys(request.params).length > 0) {
      params = { ...params, ...request.params };
    }
    if (Object.keys(request.body).length > 0) {
      params = { ...params, ...request.body };
    }

    const { method, path } = request;
    const traceId = uuid();
    request['traceId'] = traceId;
    let code = 500;
    if (exception instanceof QueryFailedError) {
      code = exception.driverError.errno;
    }
    const response = ctx.getResponse();
    const responseData = {
      code,
      message: exception.message,
      traceId,
      timestamp: new Date().toISOString(),
      path: request.url,
      method: request.method,
    };
    this.logger.log(
      `${traceId} ${method} ${path} request: ${JSON.stringify(params)} response: ${JSON.stringify(responseData)}`,
    );
    response.status(500).json(responseData);
  }
}
